///*
// * bresenham.c
// *
// *  Created on: 08/05/2013
// *      Author: alex
// */


#include "bresenham.h"

void plot(int i, int j, color_t** buffer, color_t color)
{
	if (i < 600 && j < 600)
	{
		buffer[i][j].r = color.r;
		buffer[i][j].g = color.g;
		buffer[i][j].b = color.b;
	}
}

// Pinta líneas en el octante 4
void line_bresenham_Oct4(int x0, int y0, int x1, int y1, color_t** buffer, color_t color)
{
     int Delta_O, Delta_NO, d, Xp, Yp;
     Delta_NO = -2*((y1 - y0) + (x1 - x0));
     Delta_O = -2*(y1 - y0);
     Xp = x0; Yp = y0;
     plot(Xp,Yp,buffer,color);
     d = -2 * (y1 - y0) - (x1 - x0);

     while(Xp > x1)
     {
       if (d > 0)
       {/*Pintar O*/
        Xp--;
        d += Delta_O;
       }
       else
       {/*Pintar NO*/
        Xp--; Yp++;
        d += Delta_NO;
       }
       plot(Xp,Yp,buffer,color);
     }
}
// Pinta líneas en el octante 3
void line_bresenham_Oct3(int x0, int y0, int x1, int y1, color_t** buffer, color_t color)
{
     int Delta_N, Delta_NO, d, Xp, Yp;

     Delta_N = -2*(x1 - x0);
     Delta_NO = -2*((y1 - y0) + (x1 - x0));
     Xp = x0; Yp = y0;
     plot(Xp,Yp,buffer,color);
     d = -(y1 - y0) - 2 * (x1 - x0);

     while(Yp < y1)
     {
       if (d > 0)
       {/*Pintar NO*/
        Yp++; Xp--;
        d += Delta_NO;
       }
       else
       {/*Pintar N*/
        Yp++;
        d += Delta_N;
       }
       plot(Xp,Yp,buffer,color);
     }
}
// Pinta líneas en el octante 2
void line_bresenham_Oct2(int x0, int y0, int x1, int y1, color_t** buffer, color_t color)
{
     int Delta_N, Delta_NE, d, Xp, Yp;
     Delta_NE = 2* ((y1 - y0) - (x1 - x0));
     Delta_N = -2 * (x1 - x0);
     Xp = x0; Yp = y0;
     plot(Xp,Yp,buffer,color);
     d = (y1 - y0) -  2*(x1 - x0);

     while(Yp < y1)
     {
       if (d < 0)
       {/*Pintar NE*/
        Yp++; Xp++;
        d += Delta_NE;
       }
       else
       {/*Pintar N*/
        Yp++;
        d += Delta_N;
       }
       plot(Xp,Yp,buffer,color);
     }
}
// Pinta líneas en el octante 1
void line_bresenham_Oct1(int x0, int y0, int x1, int y1, color_t** buffer, color_t color)
{
     int Delta_E, Delta_NE, d, Xp, Yp;
     Delta_E = 2*(y1-y0);
     Delta_NE = 2*((y1-y0)-(x1-x0));
     Xp = x0; Yp = y0;
     plot(Xp,Yp,buffer,color);
     d = 2* (y1-y0)-(x1-x0);
     while(Xp < x1)
     {
       if (d < 0)
       {/*Pintar E*/
        Xp++;
        d += Delta_E;
       }
       else
       {/*Pintar NE*/
        Xp++; Yp++;
        d += Delta_NE;
       }
       plot(Xp,Yp,buffer,color);
     }
}

// Dibuja una línea recta de un punto a otro
void line_Bresenham(int x0, int y0, int x1, int y1, color_t** buffer, color_t color)
{
    int temp;
    int angulo; //Es 0 si hay más x que y, 1 si hay más y que x
    long double m=0;

    // Caso en que es una linea horizontal
    if (y0 == y1)
    {
     if (x0 < x1)
       line_bresenham_Oct1(x0,y0,x1,y1,buffer,color);
     else
       line_bresenham_Oct4(x0,y0,x1,y1,buffer,color);
    }

    // Se asegura que la linea vaya de abajo para arriba
    else if (y0 > y1)
    {
      temp = y0;
      y0 = y1;
      y1 = temp;
      temp = x0;
      x0 = x1;
      x1 = temp;
    }

    if (x0 != x1)
    	m = (long double)(y1-y0)/(long double)(x1-x0);

    if (abs(y1-y0) > abs(x1-x0))
    	angulo = 1;
    else
    	angulo = 0;

    if (m < 0) // Va de derecha a izquierda
    {
		if (angulo == 1)
		  line_bresenham_Oct3(x0, y0, x1, y1, buffer, color);
		else
		  line_bresenham_Oct4(x0, y0, x1, y1, buffer, color);
    }
    else // Va de izquierda a derecha
    {
		if (angulo == 1)
		  line_bresenham_Oct2(x0, y0, x1, y1, buffer, color);
		else
		  line_bresenham_Oct1(x0, y0, x1, y1, buffer, color);
	}
}
